class KNN:
    def __init__(self, X_train, y_train, n_neighbors=3, p=2):
        self.n = n_neighbors #临近点个数
        self.p = p  #距离度量
       #X的训练样本数
        self.X_train = X_train
        #y真是标签样本数
        self.y_train = y_train
    #预测函数
    def predict(self, X):
        # 取出n个点
        knn_list = []
        for i in range(self.n):
            #dist = x1²+x2²+.....+xn²开根号
            dist = np.linalg.norm(X - self.X_train[i], ord=self.p)
            #knn_list存储的是n个的预测点到真实点的距离，并附上真实点的标签[dist1,1][dist2,0][distn,0]
            knn_list.append((dist, self.y_train[i]))

        for i in range(self.n, len(self.X_train)):
            #得到最大的距离值得索引值
            max_index = knn_list.index(max(knn_list, key=lambda x: x[0]))
            #求欧式距离值
            dist = np.linalg.norm(X - self.X_train[i], ord=self.p)
            #？？？
            if knn_list[max_index][0] > dist:
                knn_list[max_index] = (dist, self.y_train[i])

        # 统计
        #从knn_list中倒排索引
        knn = [k[-1] for k in knn_list]
        count_pairs = Counter(knn)
        #前最大n的数
        max_count = sorted(count_pairs, key=lambda x:x)[-1]
        return max_count
    #预测分数
    def score(self, X_test, y_test):
        right_count = 0
        n = 10
        for X, y in zip(X_test, y_test):
            label = self.predict(X)
            #如果预测和真实标签相等，正确个数加1
            if label == y:
                right_count += 1
        #返回预测的正确率
        return right_count / len(X_test)
